<?php
/**
 * 控制器基类
 */
namespace core;

abstract class Controller {  // 添加abstract关键字
    protected $middleware = [];  // 存储控制器中间件
    protected $view;
    protected $request;

    public function __construct()
    {
        $this->view = new View();
        $this->request = (object) $_REQUEST;
    }

    // 前置操作钩子方法 - 改为public
    public function __before() {
        // 默认空实现，子类可覆盖
    }

    // 后置操作钩子方法 - 改为public
    public function __after() {
        // 默认空实现，子类可覆盖
    }

    // 初始化方法，可被子类覆盖
    public function initialize() {
        // 初始化方法，可被子类覆盖
    }

    // 添加中间件注册方法
    protected function middleware($middleware, $options = [])
    {
        $this->middleware[] = ['name' => $middleware, 'options' => $options];
    }

    // 执行控制器中间件
    protected function executeControllerMiddleware($action, $params = [])
    {
        $middleware = $this->middleware;

        // 过滤只应用于当前操作的中间件
        $actionMiddleware = [];
        foreach ($middleware as $m) {
            if (empty($m['options']['only']) || in_array($action, $m['options']['only'])) {
                if (empty($m['options']['except']) || !in_array($action, $m['options']['except'])) {
                    $actionMiddleware[] = $m['name'];
                }
            }
        }

        // 执行中间件
        $request = $this->request;
        $next = function($request) use ($action, $params) {
            return call_user_func_array([$this, $action], $params);
        };

        return $this->runMiddleware($actionMiddleware, $request, $next);
    }

    // 运行中间件链
    private function runMiddleware(array $middleware, $request, callable $next)
    {
        if (empty($middleware)) {
            return $next($request);
        }

        $firstMiddleware = array_shift($middleware);
        $middlewareClass = 'app\\common\\middleware\\' . $firstMiddleware;

        if (class_exists($middlewareClass)) {
            $middlewareInstance = new $middlewareClass();
            if ($middlewareInstance instanceof Middleware) {
                return $middlewareInstance->handle($request, function($request) use ($middleware, $next) {
                    return $this->runMiddleware($middleware, $request, $next);
                });
            }
        }

        throw new AppException("中间件不存在: {$firstMiddleware}", 500);
    }

    // 重写调用方法，确保中间件先执行
    public function __call($method, $params)
    {
        if (method_exists($this, $method)) {
            // 执行中间件
            return $this->executeControllerMiddleware($method, $params);
        } else {
            throw new AppException("方法不存在: {$method}", 404);
        }
    }

    // 添加魔术方法，确保所有方法调用都经过__call
    public function __invoke()
    {
        // 这个方法不会被直接调用，但添加它可以确保PHP不会尝试直接调用不存在的方法
    }

    // 修改控制器方法调用方式
    public function runAction($method, $params = [])
    {
        return $this->__call($method, $params);
    }
}